package com.juzipi.demo.config;

import com.juzipi.demo.filter.JsonAuthenticationFilter;
import com.juzipi.demo.filter.TokenAuthenticationFilter;
import com.juzipi.demo.handler.JsonAccessDeniedHandler;
import com.juzipi.demo.handler.JsonAuthenticationEntryPoint;
import com.juzipi.demo.handler.JsonLoginFailureHandler;
import com.juzipi.demo.handler.JsonLoginSuccessHandler;
import com.juzipi.demo.service.MyUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


@Configuration
//开启方法权限校验
//securedEnabled: 开启@Secured注解
//prePostEnabled: 开启@PreAuthorize及@PostAuthorize注解。分别适用于进入方法前后校验，支持表达式
//@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private MyUserService myUserService;


    //重写 configure(AuthenticationManagerBuilder auth) 方法，在内存中添加两个用户。
    //使用了编码的方式进行配置后，在配置文件中配置的用户将失效。
    @Override
    //身份验证管理器生成器
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(myUserService).passwordEncoder(getPasswordEncoder());

        /*//给密码加密的吧
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        //在内存中验证用户身份？
        auth.inMemoryAuthentication().passwordEncoder(bCryptPasswordEncoder)
                //添加了一个用户 user，权限是USER
                .withUser("user")
                .password(bCryptPasswordEncoder.encode("pass"))
                .roles("USER")
                .and()
                //又添加了一个用户 admin，权限是 USER和ADMIN
                .withUser("admin")
                .password(bCryptPasswordEncoder.encode("pass"))
                .roles("USER","ADMIN");*/
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //关闭 csrf
                .and().csrf().disable()
                //禁用session
//                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//                .and().exceptionHandling()
//                .authenticationEntryPoint(new JsonAuthenticationEntryPoint())
//                .accessDeniedHandler(new JsonAccessDeniedHandler())
//                .and()
                //添加的过滤器吧
                .addFilterBefore(getTokenAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class)
                .addFilterAfter(getJsonAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                //注册自定义鉴权方法authService.isAccess
                .antMatchers("/login").permitAll()//登录允许所有
                .anyRequest().access("@authService.isAccess(request,authentication)")
                .and().formLogin().and().httpBasic();
//                .addFilterAfter(getJsonAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
//                .exceptionHandling()
//                .authenticationEntryPoint(new JsonAuthenticationEntryPoint())
//                .accessDeniedHandler(new JsonAccessDeniedHandler());
    }


    @Bean
    public JsonAuthenticationFilter getJsonAuthenticationFilter() throws Exception {

        JsonAuthenticationFilter filter = new JsonAuthenticationFilter();
        filter.setAuthenticationManager(authenticationManager());
        //自定义登录成功处理
        filter.setAuthenticationSuccessHandler(getJsonLoginSuccessHandler());
        //身份验证失败处理
        filter.setAuthenticationFailureHandler(getJsonLoginFailureHandler());

        return filter;
    }


    @Bean
    public PasswordEncoder getPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public TokenAuthenticationFilter getTokenAuthenticationFilter(){
        return new TokenAuthenticationFilter();
    }


    @Bean
    public JsonLoginFailureHandler getJsonLoginFailureHandler(){
        return new JsonLoginFailureHandler();
    }

    //登陆成功处理
    @Bean
    public JsonLoginSuccessHandler getJsonLoginSuccessHandler(){

        return new JsonLoginSuccessHandler();
    }


}
